package org.teremail.smtp;

import static org.teremail.smtp.SessionAttributes.DATA_MODE;
import static org.teremail.smtp.SessionAttributes.RECIPIENTS;
import static org.teremail.smtp.SessionAttributes.SENDER;
import static org.teremail.smtp.commands.SMTPCommand.EMPTY;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.mina.common.IoFuture;
import org.apache.mina.common.IoFutureListener;
import org.apache.mina.common.IoSession;
import org.teremail.message.Address;

import com.google.common.collect.ImmutableSet;

/**
 * Implements an Apache-MINA based SMTP Session, delegates some of the
 * calls onto an IoSession, so that it is visible in the networking
 * layer.
 * 
 * @author Michael Barker
 *
 */
public class MinaSMTPSession implements SMTPSession {

    private final IoSession ioSession;
    private final String hostName;
    private final List<String> capabilities;

    public MinaSMTPSession(IoSession session, String hostName, List<String> capabilities) {
        this.ioSession = session;
        this.hostName = hostName;
        this.capabilities = capabilities;
    }
    
    public MinaSMTPSession(IoSession session, String hostName) {
        this(session, hostName, EMPTY);
    }


    public void clearData() {
        // TODO Auto-generated method stub
        
    }

    public void close(String message) {
        ioSession.write(message).addListener(CLOSE);
    }

    private static final IoFutureListener CLOSE = new IoFutureListener() {
        public void operationComplete(IoFuture f) {
            f.getSession().close();
        }
    };
    
    
    public List<String> getCapabilities() {
        return capabilities;
    }

    public String getHostName() {
        return hostName;
    }

    public void setDataMode(boolean isDataMode) {
        ioSession.setAttribute(DATA_MODE, isDataMode);
    }
    
//    public boolean isDataMode() {
//        
//    }

    public void setSender(Address address) {
        ioSession.setAttribute(SENDER, address);
    }
    
    public Address getSender() {
        return (Address) ioSession.getAttribute(SENDER);
    }

    public void write(String message) {
        ioSession.write(message);
    }

    private Set<Address> getRecipientSet() {
        @SuppressWarnings("unchecked")
        Set<Address> recipients = (Set<Address>) ioSession.getAttribute(RECIPIENTS);
        if (recipients == null) {
            recipients = new LinkedHashSet<Address>();
            ioSession.setAttribute(RECIPIENTS, recipients);
        }
        return recipients;
    }
    
    public void addRecipient(Address address) {
        getRecipientSet().add(address);
    }

    public Collection<Address> getRecipients() {
        return ImmutableSet.copyOf(getRecipientSet());
    }

    public void clearRecipients() {
        getRecipientSet().clear();
    }

}
